package edu.zhoujw.project.infra.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/** 
 * @author: zhoujw
 * @date 2023/9/12-13:57
 * @return: 
 * @since        
 */
@Slf4j
@Configuration
@EnableAsync
@EnableScheduling
public class CustomThreadPoolConfig {

    public static final String TASK_PROGRESS_EXEC_THREAD = "T_PRGRESS_EXEC";

    @Bean(name = TASK_PROGRESS_EXEC_THREAD,destroyMethod = "shutdown")
    public ThreadPoolExecutor taskProgressExecThread() {
        int core = Runtime.getRuntime().availableProcessors();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                core * 2, core * 2, 60, TimeUnit.SECONDS
                , new ArrayBlockingQueue<>(1000)
                , r -> new Thread(r, TASK_PROGRESS_EXEC_THREAD+"-")
                , new ThreadPoolExecutor.CallerRunsPolicy()
        );

        log.info(">>>实例化任务进展线程池成功...");
        return executor;
    }


    @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)
    public Executor taskExecutor() {
        int core = Runtime.getRuntime().availableProcessors();

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(core * 2);
        executor.setMaxPoolSize(core * 2);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("custom-async-thread-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        log.info(">>>实例化默认异步执行线程池成功...");
        return executor;
    }

}
